package com.aibaixun.common.utils;


import com.aibaixun.common.constant.Constants;
import com.aibaixun.common.filter.BodyReaderHttpServletRequestWrapper;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Http请求工具类
 * @author zhangyh
 * @create 2022/4/20
 */
@Component
public class HttpUtils {

    //第三方设置的请求用户信息（appKey和secretKey用英文逗号分隔，并进行两次base64加密，放到请求头里面的Authorization参数）
    private static final String appSecret = Base64Utils.encodeData(Base64Utils.encodeData("123,456"));

    /**
     * GET请求
     * @param requestUrl
     * @return
     */
    public static JSONObject sendGetRequest(String requestUrl) {
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("GET");
            OpenApiTokenUtils apiTokenUtils = new OpenApiTokenUtils();
            String token = apiTokenUtils.getTokenForGa();
            conn.setRequestProperty("Blade-Auth",token);
            InputStream inputStream = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(isr);
            String str;
            StringBuilder builder = new StringBuilder();
            while ((str = bufferedReader.readLine()) != null) {
                builder.append(str);
            }
            conn.disconnect();
            return JSONObject.parseObject(builder.toString());
        } catch (Exception e) {
            if(e.getMessage().indexOf("401") > -1){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code",401);
                return jsonObject;
            }
            return null;
        } finally {
            // 释放资源
            try {
                if(null != bufferedReader) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
            }
        }
    }


    /**
     * POST请求
     * @param requestUrl
     * @param data
     * @return
     */
    public static Object sendJsonPostRequest(String requestUrl, String data){
        return sendHttpRequest(requestUrl, "POST", "Content-Type", "application/json; charset=UTF-8", data, null);
    }

    /**
     * XML请求方式
     * @param requestUrl
     * @param xmlInfo
     * @return
     */
    public static String sendXmlPostRequest(String requestUrl, String xmlInfo){
        return (String) sendHttpRequest(requestUrl, "POST", "Content-Type", "text/xml;charset=utf-8", null, xmlInfo);
    }

    private static Object sendHttpRequest(String requestUrl, String requestMethod,
                                          String requestPropertyKey, String requestPropertyValue,
                                          String data, String xmlInfo) {
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            if (StringUtils.isNotBlank(requestPropertyKey) && StringUtils.isNotBlank(requestPropertyValue)) {
                conn.setRequestProperty(requestPropertyKey, requestPropertyValue);
            }
            OpenApiTokenUtils apiTokenUtils = new OpenApiTokenUtils();
            String token = apiTokenUtils.getTokenForGa();
            conn.setRequestProperty("Blade-Auth",token);
            conn.setRequestProperty("Content-Type","application/json");

            OutputStream outputStream = conn.getOutputStream();
            if (StringUtils.isNotBlank(data) && StringUtils.isBlank(xmlInfo)) {
                // 在输出流中进行转码
                outputStream.write(data.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }
            if (StringUtils.isNotBlank(xmlInfo) && StringUtils.isBlank(data)) {
                // 在输出流中进行转码
                outputStream.write(xmlInfo.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }
            InputStream inputStream = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(isr);
            String str;
            StringBuilder builder = new StringBuilder();
            while ((str = bufferedReader.readLine()) != null) {
                builder.append(str);
            }
            conn.disconnect();
            if (StringUtils.isNotBlank(xmlInfo) && StringUtils.isBlank(data)) {
                return builder.toString();
            } else {
                return JSONObject.parseObject(builder.toString());
            }
        } catch (Exception e) {
            return e.getMessage();
        } finally {
            // 释放资源
            try {
                if(null != bufferedReader) {
                    bufferedReader.close();
                }
            } catch (IOException e) {
            }
        }
    }

    /**
     * 获取全部参数(包括URL和Body上的) \
     * @param request
     * @return
     */
    public static SortedMap<String, String> getAllParams(HttpServletRequest request) throws IOException {
        SortedMap<String, String> sortedMap = new TreeMap<>();
        //获取Header上的参数
        //应用id
        String appId = request.getHeader(Constants.APP_ID);
        sortedMap.put(Constants.APP_ID, appId);
        //时间戳,增加链接的有效时间,超过阈值,即失效
        String timeStamp = request.getHeader(Constants.TIME_STAMP);
        sortedMap.put(Constants.TIME_STAMP, timeStamp);
        //获取调用方的签名
        String sign = request.getHeader(Constants.SIGN);
        sortedMap.put(Constants.SIGN, sign);
        //获取parameters（对应@RequestParam）
        Map<String, String[]> requestParams = null;
        if (!CollectionUtils.isEmpty(request.getParameterMap())) {
            requestParams = request.getParameterMap();
            //获取GET请求参数,以键值对形式保存
            for (Map.Entry<String, String[]> entry : requestParams.entrySet()) { //{username:[xx],password:[xx]}
                sortedMap.put(entry.getKey(), entry.getValue()[0]);
            }
        }
        // 分别获取了request inputstream中的body信息、parameter信息
        //获取body（对应@RequestBody）
        if (request instanceof BodyReaderHttpServletRequestWrapper) {
            BodyReaderHttpServletRequestWrapper requestWrapper = (BodyReaderHttpServletRequestWrapper) request;
            try {
                JSONObject data = JSONObject.parseObject(requestWrapper.getBody());
                //获取POST请求的JSON参数,以键值对形式保存
                for (Map.Entry<String, Object> entry : data.entrySet()) {
                    sortedMap.put(entry.getKey(), entry.getValue().toString());
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return sortedMap;
    }
}
